package dao.implementations.postgresql;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import dao.implementations.DBBase;
import dao.interfaces.IUsuario;
import dao.transferObjects.UsuarioTO;
import dao.transferObjects.UsuarioUnificadoTO;
import dao.transferObjects.Administrador.AdministradorTO;
import dao.transferObjects.Docente.DocenteTO;
import dao.transferObjects.Gae.GaeTO;
import dao.transferObjects.Socio.DireccionTO;
import dao.transferObjects.Socio.SocioTO;

public class UsuarioDB extends DBBase implements IUsuario{
	
	public UsuarioDB(Connection connection){
		this.conn = connection;
	}
	
	private static String CAMPOS_USUARIO = " rut, verificador, contrasena, tipo, eliminado ";
	
	public int obtenerSgteIDnew_new()
	{
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		int resp = -1;
		String query = "SELECT nextval('new_new_id_new_seq') as NEXTVAL";
		
		try
		{						
			pstmt = conn.prepareStatement(query);
						
			rs = pstmt.executeQuery();
			
			if(rs.next())
				resp = rs.getInt("NEXTVAL");
			
			pstmt.close();
			rs.close();
			
		}
		catch (SQLException sqle) {
			System.out.print("Error en UsuarioDB -> obtenerSgteIDnew_new() : " + sqle.getMessage());
		}
		finally{
			if (pstmt != null) {
		          try {
		               pstmt.close();
		               
		          } catch (SQLException e) {
		               e.printStackTrace();
		          }
			}
		}		
		return resp;
	}
	
	@Override
	public int guardarHora(){
		PreparedStatement insertUser = null;
		int result = 0;
		int id_new = obtenerSgteIDnew_new();
		
		String query = "INSERT INTO new_new (id_new, fecha_hora) VALUES (?, ?);";
		
		java.util.Date a = new java.util.Date();
		
		//Fecha Completa
		SimpleDateFormat sdf_full = new SimpleDateFormat("dd/MMM/yyyy HH:mm:ss,SSS");
		System.out.println("sdf_full: --> "+sdf_full.format(a));
		
		//Fecha
		SimpleDateFormat sdf_anio = new SimpleDateFormat("yyyy");
		SimpleDateFormat sdf_mes = new SimpleDateFormat("MMM");
		SimpleDateFormat sdf_dia = new SimpleDateFormat("dd");
		
		System.out.println("sdf_anio: --> "+sdf_anio.format(a));
		System.out.println("sdf_mes: --> "+sdf_mes.format(a));
		System.out.println("sdf_dia: --> "+sdf_dia.format(a));
		
		//Hora
		SimpleDateFormat sdf_hora = new SimpleDateFormat("HH");
		SimpleDateFormat sdf_minuto = new SimpleDateFormat("mm");
		SimpleDateFormat sdf_segundo = new SimpleDateFormat("ss");
		SimpleDateFormat sdf_miliseg = new SimpleDateFormat("SSS");
		
		System.out.println("sdf_hora: --> "+sdf_hora.format(a));
		System.out.println("sdf_minuto: --> "+sdf_minuto.format(a));
		System.out.println("sdf_segundo: --> "+sdf_segundo.format(a));
		System.out.println("sdf_miliseg: --> "+sdf_miliseg.format(a));
		
		long lnMilisegundos = a.getTime();
		Timestamp ts = new Timestamp(lnMilisegundos);
		
		System.out.println("Date.getTime: --> "+a.getTime());
		System.out.println("Timestamp: --> "+ts);
		
		/// OTRA FORMA
		Date d = new Date();
		Calendar c = Calendar.getInstance();
		c.setTime(d);
		int anio = c.get(Calendar.YEAR);
		int mes = c.get(Calendar.MONTH)+1;
		int dia = c.get(Calendar.DAY_OF_MONTH);
		System.out.println("anio: --> "+anio);
		System.out.println("mes: --> "+mes);
		System.out.println("dia: --> "+dia);
		
		int hora = c.get(Calendar.HOUR_OF_DAY);
		int minuto = c.get(Calendar.MINUTE);
		int segundo = c.get(Calendar.SECOND);
		int miliseg = c.get(Calendar.MILLISECOND);
		System.out.println("hora: --> "+hora);
		System.out.println("minuto: --> "+minuto);
		System.out.println("segundo: --> "+segundo);
		System.out.println("miliseg: --> "+miliseg);
		
		try{
			insertUser = this.conn.prepareStatement(query);
			insertUser.setInt(1, id_new);
			insertUser.setTimestamp(2, ts);
			result = insertUser.executeUpdate();
			insertUser.close();
		}
		catch (SQLException ex)
		{
			System.out.println("Error en la clase UsuarioDB -> guardarHora -> "+ ex.getMessage());
		}		
		return result;
	}
	
	private UsuarioUnificadoTO resultSet_a_UsuarioUnificadoTO(ResultSet rs, String tipoUsuario)
	{
		UsuarioUnificadoTO usuarioUnido = new UsuarioUnificadoTO();
		
		UsuarioTO usr = new UsuarioTO();
		AdministradorTO admin = new AdministradorTO();
		DocenteTO doc = new DocenteTO();
		GaeTO gae = new GaeTO();
		SocioTO soc = new SocioTO();
		DireccionTO dir = new DireccionTO();
		
		try
		{
			usr.setRut(rs.getInt("rut"));
			usr.setVerificador(rs.getString("verificador"));
			usr.setContrasena(rs.getString("contrasena"));
			usr.setTipo(rs.getString("tipo"));
			usr.setEliminado(rs.getBoolean("eliminado"));
			
			usuarioUnido.setUsuario(usr);
			
			if(tipoUsuario.equals("administrador"))
			{				
				admin.setNombre(rs.getString("nombre"));
				admin.setApellido(rs.getString("apellido"));
				admin.setCorreo(rs.getString("correo"));
				admin.setTipo_fono(rs.getString("tipo_fono"));
				admin.setFono(rs.getInt("fono"));
				admin.setRut_admin(rs.getInt("rut"));
				admin.setEliminado(rs.getBoolean("eliminado_admin"));
				
				usuarioUnido.setAdministrador(admin);
			}
			if(tipoUsuario.equals("docente"))
			{				
				doc.setNombre(rs.getString("nombre"));
				doc.setApellido(rs.getString("apellido"));
				doc.setCorreo(rs.getString("correo"));
				doc.setTipo_fono(rs.getString("tipo_fono"));
				doc.setFono(rs.getInt("fono"));
				doc.setRut_docente(rs.getInt("rut"));
				doc.setEliminado(rs.getBoolean("eliminado_doc"));
				
				usuarioUnido.setDocente(doc);				
			}
			if(tipoUsuario.equals("socio"))
			{
				soc.setNombre(rs.getString("nombre_socio"));
				soc.setDescripcion(rs.getString("descripcion"));
				soc.setNombreEncargado(rs.getString("nombre_encargado"));
				soc.setApellidoEncargado(rs.getString("apellido_encargado"));
				soc.setTipo_fono(rs.getString("tipo_fono"));
				soc.setFono(rs.getInt("fono"));
				soc.setCorreo(rs.getString("correo"));
				soc.setRut_socio(rs.getInt("rut"));
				soc.setEliminado(rs.getBoolean("eliminado_soc"));
				
				usuarioUnido.setSocio(soc);
				
				dir.setRut_socio(rs.getInt("rut"));
				dir.setRegion(rs.getString("region"));
				dir.setCiudad(rs.getString("ciudad"));
				dir.setComuna(rs.getString("comuna"));
				dir.setPoblacion(rs.getString("poblacion"));
				dir.setCalle(rs.getString("calle"));
				dir.setNumero(rs.getString("numero"));
				
				//usuarioUnido.socio.setDireccion(dir);
				usuarioUnido.getSocio().setDireccion(dir);
			}
			if(tipoUsuario.equals("gae"))
			{
				gae.setId_gae(rs.getInt("id_gae"));
				gae.setRut_gae(rs.getInt("rut_gae"));
				gae.setNombre_gae(rs.getString("nombre_gae"));
				gae.setId_proyecto(rs.getInt("id_proyecto"));
				gae.setId_curso(rs.getInt("id_curso"));
				gae.setCtd_alumno(rs.getInt("cantidad_alumnos"));
				gae.setNombreRepresentante(rs.getString("nombre_representante"));
				gae.setApellidoRepresentante(rs.getString("apellido_representante"));
				gae.setTipo_fono(rs.getString("tipo_fono"));
				gae.setFono(rs.getInt("fono"));
				gae.setCorreo(rs.getString("correo"));
				gae.setNota1(rs.getDouble("nota1"));
				gae.setNota2(rs.getDouble("nota2"));
				gae.setNota3(rs.getDouble("nota3"));
				gae.setNota_socio(rs.getDouble("nota_socio"));
				gae.setNota_final(rs.getDouble("nota_final"));
				gae.setEliminado(rs.getBoolean("eliminado_gae"));
				gae.setMatriculaRepresentante(rs.getInt("matricula_representante"));
				
				usuarioUnido.setGae(gae);
			}
			
		}
		catch (SQLException e){
			System.out.println("Error en "+this.getClass().getCanonicalName()+" -> resultSet_a_UsuarioTO : " + e.getMessage());
		}
		return usuarioUnido;
	}
	
	private UsuarioTO resultSet_a_UsuarioTO(ResultSet rs)
	{
		UsuarioTO usr = new UsuarioTO();
		
		try{
			usr.setRut(rs.getInt("rut"));
			usr.setVerificador(rs.getString("verificador"));
			usr.setContrasena(rs.getString("contrasena"));
			usr.setTipo(rs.getString("tipo"));
			usr.setEliminado(rs.getBoolean("eliminado"));
		}
		catch (SQLException e){
			System.out.println("Error en "+this.getClass().getCanonicalName()+" -> resultSet_a_UsuarioTO : " + e.getMessage());
		}
		return usr;
	}
	
	
	public UsuarioTO obtenerUsuario(int rut, String contrasena) {
		
		UsuarioTO usuario = new UsuarioTO();
		
		PreparedStatement pstmt = null;
		
		ResultSet rs = null;
		
		String query =  "SELECT " + CAMPOS_USUARIO +
		  				"FROM usuario "+
		  				"WHERE rut = ? AND contrasena = ? "; 
		try{
			pstmt = this.conn.prepareStatement(query);
			pstmt.setInt(1, rut);
			pstmt.setString(2, contrasena);
			
			rs = pstmt.executeQuery();
			
			if(rs.next())
				usuario = resultSet_a_UsuarioTO(rs);
		}
		catch (SQLException sqle)
		{
			System.out.println("Error en la clase UsuarioDB -> "+ sqle.getMessage());
		}
		catch (Exception ex) {
			System.out.println("Error en la Aplicacion en el metodo obtenerUsuario : " + ex.getMessage());
		}
		finally{
			if (pstmt != null) {
				try {
					if(rs != null){						
						rs.close();
			            pstmt.close();
					}
			    } catch (SQLException e) {
			               e.printStackTrace();
			    }				
			}
		}
		return usuario;
	}
	
	public UsuarioTO obtenerUsuarioRut(int rut)
	{
		UsuarioTO usuario = null;
		
		PreparedStatement pstmt = null;
		
		ResultSet rs = null;
		
		String query =  "SELECT " + CAMPOS_USUARIO +
		  				"FROM usuario "+
		  				"WHERE rut = ?"; 
		try{
			pstmt = this.conn.prepareStatement(query);
			pstmt.setInt(1, rut);
			
			rs = pstmt.executeQuery();
			
			if(rs.next())
				usuario = resultSet_a_UsuarioTO(rs);
		}
		catch (SQLException sqle)
		{
			System.out.println("Error en la clase UsuarioDB -> "+ sqle.getMessage());
		}
		catch (Exception ex) {
			System.out.println("Error en la Aplicacion en el metodo obtenerUsuarioRut : " + ex.getMessage());
		}
		finally{
			if (pstmt != null) {
				try {
					if(rs != null){						
						rs.close();
			            pstmt.close();
					}
			    } catch (SQLException e) {
			               e.printStackTrace();
			    }				
			}
		}
		return usuario;
	}
	
	public UsuarioTO obtenerUsuarioLogeado(int rut, String tipoUsuario){
		UsuarioTO usuario = new UsuarioTO();
		
		String query =  " SELECT " + CAMPOS_USUARIO +
						" FROM usuario "+
						" WHERE rut = ? AND tipo = ?"; 
		
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try{
			pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, rut);
			pstmt.setString(2, tipoUsuario);
			rs = pstmt.executeQuery();
			
			if(rs.next())
				usuario = resultSet_a_UsuarioTO(rs);
			rs.close();
		}
		catch (SQLException sqle) {
			System.out.println("Error en "+this.getClass().getCanonicalName()+" -> obtenerUsuarioLogeado : " + sqle.getMessage());
		}
		finally{
			if (pstmt != null) {
		          try {
		               pstmt.close();
		               
		          } catch (SQLException e) {
		               e.printStackTrace();
		          }
			}
		}
		
		return usuario;
	}
	
	public int registrarUsuario(UsuarioTO usuario)
	{
		PreparedStatement insertUser = null;
		int result = 0;
		
		//String query = "INSERT INTO usuario(rut, verificador, contrasena, tipo, eliminado) VALUES (?, ?, ?, ?, ?)";
		String query = "INSERT INTO usuario(" + CAMPOS_USUARIO + ") VALUES (?, ?, ?, ?, ?)";
		
		try{
			insertUser = this.conn.prepareStatement(query);
			insertUser.setInt(1, usuario.getRut());
			insertUser.setString(2, usuario.getVerificador());
			insertUser.setString(3, usuario.getContrasena());
			insertUser.setString(4, usuario.getTipo());
			insertUser.setBoolean(5, usuario.getEliminado());
			result = insertUser.executeUpdate();
		}
		catch (SQLException ex)
		{
			System.out.println("Error en la clase UsuarioDB -> registrarUsuario -> "+ ex.getMessage());
		}		
		return result;
	}
	
	public int modificarUsuario(UsuarioTO usuario)
	{
		PreparedStatement updateUser = null;
		int result = 0;
		
		String query = " UPDATE usuario "+
					   " SET contrasena=?, eliminado=? "+
					   " WHERE rut=?;";
		
		try{
			updateUser = this.conn.prepareStatement(query);
			updateUser.setString(1, usuario.getContrasena());
			updateUser.setBoolean(2, usuario.getEliminado());
			updateUser.setInt(3, usuario.getRut());
			result = updateUser.executeUpdate();
			updateUser.close();
		}
		catch (SQLException ex)
		{
			System.out.println("Error en la clase UsuarioDB -> modificarUsuario -> "+ ex.getMessage());
		}		
		return result;
	}
	public int eliminarUsuario(UsuarioTO usuario){
		PreparedStatement updateUser = null;
		int result = -1;
		
		String query = " DELETE FROM usuario "+
					   " WHERE rut=?;";
		
		try{
			updateUser = this.conn.prepareStatement(query);
			updateUser.setInt(1, usuario.getRut());
			result = updateUser.executeUpdate();
			updateUser.close();
		}
		catch (SQLException ex)
		{
			System.out.println("Error en la clase UsuarioDB -> eliminarUsuario -> "+ ex.getMessage());
		}		
		return result;
	}
}
